package com.rxyb.redis.utils;

import com.rxyb.redis.constant.RedisConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author duyh
 * @date 2020/6/5
 */
@Slf4j
@Service
public class RedisObjectUtils {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * redis设置值和有效时间
     *
     * @param key
     * @param value
     * @param EXPIRE_TIME
     * @param timeUnit
     */
    public void putObject(Object key, Object value, long EXPIRE_TIME, TimeUnit timeUnit) {
        try {
            ValueOperations opsForValue = redisTemplate.opsForValue();
            opsForValue.set(key, value, EXPIRE_TIME, timeUnit);
            log.debug("redis设置");
        } catch (Throwable t) {
            log.error("redis设置异常", t);
        }
    }

    /**
     * redis设置值和有效时间
     *
     * @param key
     * @param value
     * @param timeout 秒
     */
    public void set(String key, String value, long timeout) {
        redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
    }

    /**
     * 设置键值
     *
     * @param key
     * @param value
     */
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * redis设置值和有效时间
     *
     * @param key
     * @param value
     * @param timeout 秒
     */
    public void set(String group, String key, String value, long timeout) {
        redisTemplate.opsForValue().set(RedisConstant.OBJECT + "_" + group + "_" + key, value, timeout, TimeUnit.SECONDS);
    }

    /**
     * 清除所有缓存
     */
    public void clear() {
        redisTemplate.execute((RedisCallback) connection -> {
            connection.flushDb();
            return null;
        });
    }

    /**
     * 通过key删除缓存
     *
     * @param key
     * @return
     */
    public boolean removeObject(Object key) {
        try {
            redisTemplate.delete(key);
            log.debug("redis删除");
            return true;
        } catch (Throwable t) {
            log.error("redis删除失败", t);
            return false;
        }
    }

    /**
     * 通过key获取值
     *
     * @param key
     * @return
     */
    public Optional<Object> get(String key) {
        Object s = redisTemplate.opsForValue().get(key);
        if (null == s) {
            return Optional.empty();
        }
        return Optional.of(s);
    }

    /**
     * 根据key获取redis的值
     *
     * @param key
     * @return
     */
    public Optional<Object> get(String group, String key) {
        Object s = redisTemplate.opsForValue().get(RedisConstant.REDIS_STRING + "_" + group + "_" + key);
        if (null == s) {
            return Optional.empty();
        }
        return Optional.of(s);
    }

    /**
     * 根据key删除redis
     *
     * @param key
     */
    public void del(String key) {
        redisTemplate.delete(key);
    }

    /**
     * 根据key删除redis
     *
     * @param key
     */
    public void del(String group, String key) {
        redisTemplate.delete(RedisConstant.REDIS_STRING + "_" + group + "_" + key);
    }

    /**
     * 根据key删除redis
     *
     * @param group
     */
    public void delgroup(String group) {
        //最后一定要带上 *
        Set<String> keys = redisTemplate.keys(RedisConstant.REDIS_STRING + "_" + group + "_*");
        redisTemplate.delete(keys);
    }

    /**
     * 判断redis中是否已存在key对应的value
     *
     * @param key
     * @return
     */
    public boolean isExistValue(String key) {
        if (StringUtils.isBlank(key)) {
            return false;
        }
        // 根据key获取redis的value
        Object value = redisTemplate.opsForValue().get(key);
        if (null == value) {
            return false;
        }
        return true;
    }


    /**
     * 判断redis中是否已存在key
     *
     * @param key
     * @return
     */
    public boolean isExistKey(String key) {
        if (StringUtils.isBlank(key)) {
            return false;
        }
        return redisTemplate.hasKey(key);
    }

    /**
     * 设置失效时间
     *
     * @param key
     * @param timeout
     * @return
     */
    public boolean expire(String key, long timeout) {
        Boolean result = redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
        log.info("redis设置有效时间处理结果【{}】", result);
        if (null != result && result == true) {
            return true;
        }
        return false;
    }

    /**
     * 根据key获取过期时间
     *
     * @param key
     * @return
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }


    /**
     * redis给key设置失效时间
     *
     * @param key
     * @param timeUnit
     * @param times
     */
    public boolean setExpire(String key, TimeUnit timeUnit, long times) {
        if (StringUtils.isEmpty(key)) {
            log.debug("key值为空");
            return false;
        }
        if (times < 0) {
            log.debug("过期时间必须大于0");
            return false;
        }
        try {
            redisTemplate.expire(key, times, timeUnit);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}
